Wiki
- Library Entry
Intent:
Provide a way to access the elements of a aggregate
object without exposing its underlying representation.
Applicability:
-
You have some object classes which
encapsulate aggregations of other objects and you wish to hide details of
the structures to minimize the effects of future changes.
-
You need to perform various operations which
must traverse the elements of the aggregate structure in various ways.
-
You want to avoid polluting the interface
of the aggregate objects with those operations to simplify future changes or
additions.
-
You wish to provide a common polymorphic
interface for iteratively traversing different aggregate structures to
perform those operations.
Solution:
1.
Create an Iterator class interface which defines a basic, uniform set of
functions for traversing and accessing elements. Create an Aggregate class
interface for maintainance of an aggregate structure and creation of Iterator(s)
for traversal.
2.
Define the SpecificAggregate classes to implement an Aggregate structure
of specific Elements.
3.
For each method of traversal needed, create a ConcreteIterator which
implements the Iterator interface to traverse and access elements encapsulated
by a SpecificAggregate class.
4.
Create the Element class for objects which will be encapsulated by
Aggregate and returned by the traversal functions implemented by the
ConcreteIterator(s).
5.
Note:
The Iterator and Aggregate class interfaces are typically defined in C++ using
class templates, for example, see the C++ STL library.
Consequences:
-
Downcasting may not be required to access
elements of the aggregate structure (unless the elements are formed from an
inheritance hierarchy).
-
A variety of structure traversal methods can
be easily supported.
-
Usage of iterators simplifies the interface
of Aggregate objects.
-
Multiple traversals can be performed on a
single structure at the same time since the iterators must store the current
position.
-
Application may require changes to existing
code, which may be unacceptable if the base classes resides in a reuse
libarary.
-
Adding a new iterator requires adding a new
GetIterator function to every SpecificAggregate (many solutions separate
construction of ConcreteIterators from the Aggregate class to avoid this
problem.)
-
If the SpecificAggregate encapsulates
elements related through an inheritance hierarchy, the downcasting may be
needed to access specific members of the element classes.